﻿/*

Copyright 2009 Guillaume Amringer

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

package {
	import flash.display.MovieClip;
	import br.com.stimuli.loading.BulkLoader;
	import br.com.stimuli.loading.BulkProgressEvent;
	import events.InterfaceEvent;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import org.papervision3d.cameras.Camera3D;
	import org.papervision3d.core.culling.FrustumTestMethod;
	import org.papervision3d.core.math.Number3D;
	import org.papervision3d.core.math.Plane3D;
	import org.papervision3d.materials.utils.MaterialsList;
	import org.papervision3d.objects.DisplayObject3D;
	import org.papervision3d.objects.primitives.Cube;
	import org.papervision3d.objects.primitives.Plane;
	import org.papervision3d.render.BasicRenderEngine;
	import org.papervision3d.render.QuadrantRenderEngine;
	import org.papervision3d.scenes.Scene3D;
	import org.papervision3d.view.Viewport3D;
	import org.papervision3d.materials.ColorMaterial;
	import org.papervision3d.events.InteractiveScene3DEvent;
	import lt.uza.utils.Global;
	
	public class GameInterface extends Interface{
		
		private var _assetsLoader:BulkLoader = new BulkLoader('gameInterfaceLoader');
		
//		private var _tl:MovieClip = new MovieClip();
		
		private var _menuBox:MenuBox = new MenuBox();
		
		public var mouse3DPos:Number3D;
		
		public var camera:Camera3D = new Camera3D(60, 10, 50000);
		public var cameraInterest:DisplayObject3D = new Cube(new MaterialsList({all:new ColorMaterial(0xff00ff)}), 150,150,150);// DisplayObject3D.ZERO;
		public var scene:Map;
		private var _viewport:Viewport3D = new Viewport3D(0, 0, true, true);
		private var _renderEngine:QuadrantRenderEngine = new QuadrantRenderEngine();
		
		private var _blackBG:MovieClip = new MovieClip();
		
		public const BORDER_MOUSE_MOVE_CAMERA_WIDTH:uint = 30;
		public const CAMERA_MOVEMENT:uint = 100;
		public const MIN_CAMERA_DISTANCE:uint = 300;
		public const MAX_CAMERA_DISTANCE:uint = 3000;
		
		private var _rotationInitialX:uint = 0;
		private var _rotationInitialY:uint = 0;
		private var _cameraDist:uint;
		private var _rotating:Boolean = false;
		
		public function GameInterface():void {
			
			camera.target = cameraInterest;
			
//			_assetsLoader.add('interface/menu/tl.png', { id:'tl' } );
//			_assetsLoader.addEventListener(BulkProgressEvent.COMPLETE, _assetsLoadingCompleteHandler);
			_blackBG.addEventListener(MouseEvent.RIGHT_CLICK, _BGRightClickHandler);
			_blackBG.addEventListener(MouseEvent.CLICK, _BGClickHandler);
			this.addEventListener(MouseEvent.MOUSE_DOWN, _mouseDownHandler);
			this.addEventListener(MouseEvent.MOUSE_UP, _mouseUpHandler);
			this.addEventListener(MouseEvent.MOUSE_WHEEL, _mouseWheelHandler);
		}
		
		public function changetext(pText:String):void {
			_menuBox.changetext(pText);
		}
		
		public override function build():void {
			//_assetsLoader.start();
			this._constructInterface();
		}
		
		public override function resize():void {
			
			//	Menu box
			_menuBox.x = 0;
			_menuBox.y = 0;
			
			//	Viewport
			_viewport.x = 0;
			_viewport.y = 0;
			
			//	Black Background
			_blackBG.x = 0;
			_blackBG.y = 0;
			_blackBG.width = globals.width;
			_blackBG.height = globals.height;
		}
		
		public function startRendering():void {
			
			//	Start rendering event listener
			this.addEventListener(Event.ENTER_FRAME, _enterFrameHandler);
		}
		
		private function _assetsLoadingCompleteHandler(e:BulkProgressEvent):void {
//			_tl.addChild(_assetsLoader.getBitmap('tl'));
			
			this._constructInterface();
		}
		
		private function _constructInterface():void {
			
			_blackBG.graphics.beginFill(0x0000000);
			_blackBG.graphics.drawRect(0, 0, globals.width, globals.height);
			
			//	Add elements
			this.resize();
			this.addChild(_blackBG);
			this.addChild(_viewport);
			this.addChild(_menuBox);
			
			this.dispatchEvent(new InterfaceEvent(InterfaceEvent.READY));
		}
		
		private function _enterFrameHandler(e:Event):void {
			
			scene.enterFrameHandler();
			
			//	Camera movement
			if (this.mouseX > globals.width - BORDER_MOUSE_MOVE_CAMERA_WIDTH){
				camera.moveRight(CAMERA_MOVEMENT);
				cameraInterest.moveRight(CAMERA_MOVEMENT);
				if (cameraInterest.distanceTo(globals.game.map.center) > Map.RADIUS) {
					camera.moveLeft(CAMERA_MOVEMENT);
					cameraInterest.moveLeft(CAMERA_MOVEMENT);
				}
			}
			if (this.mouseX < BORDER_MOUSE_MOVE_CAMERA_WIDTH){
				camera.moveLeft(CAMERA_MOVEMENT);
				cameraInterest.moveLeft(CAMERA_MOVEMENT);
				if (cameraInterest.distanceTo(globals.game.map.center) > Map.RADIUS) {
					camera.moveRight(CAMERA_MOVEMENT);
					cameraInterest.moveRight(CAMERA_MOVEMENT);
				}
			}
			if (this.mouseY > globals.height - BORDER_MOUSE_MOVE_CAMERA_WIDTH){
				camera.moveDown(CAMERA_MOVEMENT);
				cameraInterest.moveDown(CAMERA_MOVEMENT);
				if (cameraInterest.distanceTo(globals.game.map.center) > Map.RADIUS) {
					camera.moveUp(CAMERA_MOVEMENT);
					cameraInterest.moveUp(CAMERA_MOVEMENT);
				}
			}
			if (this.mouseY < BORDER_MOUSE_MOVE_CAMERA_WIDTH){
				camera.moveUp(CAMERA_MOVEMENT);
				cameraInterest.moveUp(CAMERA_MOVEMENT);
				if (cameraInterest.distanceTo(globals.game.map.center) > Map.RADIUS) {
					camera.moveDown(CAMERA_MOVEMENT);
					cameraInterest.moveDown(CAMERA_MOVEMENT);
				}
			}
			
			//	Camera rotation
			if (_rotating) {
				//cameraInterest.rota
				changetext((this.mouseX - _rotationInitialX).toString() + ' - ' + (this.mouseY - _rotationInitialY).toString());
				camera.target = null;
				camera.rotationX += this.mouseY - _rotationInitialY;
				_rotationInitialY = this.mouseY;
				camera.rotationY += this.mouseX - _rotationInitialX;
				_rotationInitialX = this.mouseX;
				camera.moveForward(_cameraDist);
				cameraInterest.copyPosition(camera);
				camera.moveBackward(_cameraDist);
				camera.target = cameraInterest;
			}
			
			//	Render
			_renderEngine.renderScene(scene, camera, _viewport);
			
			//	Check mouse intersect
			var ray:Number3D = camera.unproject(_viewport.containerSprite.mouseX, _viewport.containerSprite.mouseY);
			ray = Number3D.add(ray, camera.position);
			scene.floor.setNormalAndPoint(new Number3D(0, 1, 0), new Number3D(0, 0, 0));
			mouse3DPos = scene.floor.getIntersectionLineNumbers(camera.position, ray);
		}
		
		private function _BGClickHandler(e:MouseEvent):void {
			globals.game.unitsManager.clearSelection();
		}
		
		private function _BGRightClickHandler(e:MouseEvent):void {
			globals.game.unitsManager.moveSelection(globals.game.gameInterface.mouse3DPos);
		}
		
		private function _mouseWheelHandler(e:MouseEvent):void {
			if(e.delta > 0 && camera.distanceTo(cameraInterest) > MIN_CAMERA_DISTANCE)
				camera.moveForward(CAMERA_MOVEMENT);
			else if (e.delta < 0 && camera.distanceTo(cameraInterest) < MAX_CAMERA_DISTANCE)
				camera.moveBackward(CAMERA_MOVEMENT);
			_cameraDist = camera.distanceTo(cameraInterest);
		}
		
		private function _mouseDownHandler(e:MouseEvent):void {
			_rotationInitialX = this.mouseX;
			_rotationInitialY = this.mouseY;
			_rotating = true;
		}
		
		private function _mouseUpHandler(e:MouseEvent):void {
			_rotating = false;
		}
	}
}